
#include "LoiterBehaviour.h"
#include "../Ship.h"
#include "../Utils/Vector2D.h"
#include "../Utils/Util.h"
#include "../World.h"
#include "../Map.h"

#include <cassert>


LoiterBehaviour::LoiterBehaviour(Ship *my_ship, Vector2D loiter_point, float max_dist) :
    my_ship(my_ship),
    loiter_point(loiter_point),
    max_dist(max_dist) {

    assert(my_ship != NULL);
    path_find = NULL;
}

LoiterBehaviour::~LoiterBehaviour(){
    if(path_find != NULL){
        delete path_find;
    }
}

bool LoiterBehaviour::shouldILoiter(void){
    return true;
}

bool LoiterBehaviour::perform(void){
    if(path_find == NULL){
        path_find = new PathFindBehaviour(my_ship, generateDestination());
    }

    if(!path_find->make_valid()){
        clear();
        path_find = new PathFindBehaviour(my_ship, generateDestination());
    }

    if(path_find->goToTarget()){
        clear(); 
    }

    return false; // we never finish loitering
}

Vector2D LoiterBehaviour::generateDestination(void){
    Map *map = World::instance().getMap();
    Vector2D min_coord = map->getMinCoord();
    Vector2D max_coord = map->getMaxCoord();

    
    float offset = my_ship->getSize();
    Vector2D sample = Vector2D(Util::rand_interval(min_coord.x+offset, max_coord.x-offset),
                               Util::rand_interval(min_coord.y+offset, max_coord.y-offset));
    Vector2D tmp1, tmp2, tmp3;

    while((sample-loiter_point).length() > max_dist ||
           map->collideSphere(sample, my_ship->getSize()*5.0f, tmp1, tmp2, tmp3) || 
           map->pointInsideObstacle(sample, true, false) ||
          (sample-my_ship->getPosition()).length() < max_dist/3.0f){

        sample = Vector2D(Util::rand_interval(min_coord.x+offset, max_coord.x-offset),
                          Util::rand_interval(min_coord.y+offset, max_coord.y-offset));
    }

    return sample;
}

void LoiterBehaviour::clear(void){
    if(path_find != NULL){
        delete path_find;
        path_find = NULL;
    }
}

